//LiteXLoader Dev Helper
/// <reference path="e:\vsCodePlugins\mcide/Library/JS/Api.js" /> 

/**
 * 插件模板:YoyoRobot 机器人ws 对接模板
 * 作者:Yoyo
 * 版本:v0.0.4
 */

const webConfig = {
    host: '127.0.0.1',//地址
    port: 5000,//端口
    key: 'beacOTtJK%'//key密钥
};


ll.registerPlugin('YoyoRobot-WebSocket模板', '这是一个机器人websocket模板插件', [0, 0, 4], { author: 'Yoyo' });//注册插件

class wsRobot {

    /**
     * 监听群聊事件
     * @param {Object} e 
     */
    messageGroup(e) {
        if (e.group_id != '569211842') return;
        log('接收群消息:', e);
        yoyo.client.sendGroupMsg(e.group_id,'Hello world!').then(ress=>{
            log('函数回调:',ress);
        });

        // yoyo.client.sendGroupMsg(e.group_id,yoyo.segment.record('https://www.runoob.com/try/demo_source/horse.mp3'));

        // yoyo.client.sendGroupMsg(e.group_id,yoyo.segment.xml(`<?xml version='1.0' encoding='UTF-8' standalone='yes' ?><msg serviceID="35" templateID="1" action="viewMultiMsg" brief="[聊天记录]" m_resid="Nmlbbvk3Kgs1lb2oKb5N8z/65FSpRdomRALEOA5d7z8pvFoyE2GeDfok4gd8jLPp" m_fileName="7187957688544367155" tSum="2" sourceMsgId="0" url="" flag="3" adverSign="0" multiMsgFlag="0"><item layout="1" advertiser_id="0" aid="0"><title size="34" maxLines="2" lineSpace="12">群聊的聊天记录</title><title size="26" color="#777777" maxLines="4" lineSpace="12">影:  @.death &amp; life 发给我</title><title size="26" color="#777777" maxLines="4" lineSpace="12">.death &amp; li...:  我一般直接备份到网盘</title><hr hidden="false" style="0" /><summary size="26" color="#777777">查看2条转发消息</summary></item><source name="聊天记录" icon="" action="" appid="-1" /></msg>`));
        // yoyo.client.sendGroupMsg(e.group_id, [yoyo.segment.at(e.sender.user_id), yoyo.segment.face(178)]);
        yoyo.client.sendGroupMsg(e.group_id, ['看美女', yoyo.segment.image('https://img1.baidu.com/it/u=4128078998,2997625627&fm=253&app=120&size=w931&n=0&f=JPEG&fmt=auto?sec=1673715600&t=a3782efc6d96e7881477f50f05857127')]);
    }

    /**
     * 监听私聊事件
     * @param {Object} e 
     */
    messagePrivate(e) {
        log('接收私聊:', e.raw_message);
    }

    /**
     * 监听群私聊事件
     * @param {Object} e 
     */
    messagePrivateGroup(e) {

    }

    /**
     * 群员增加事件 (自己入群、他人入群)
     * @param {Object} e 
     */
    noticeGroupIncrease(e) {

    }

    /**
     * 监听成员(退群/被踢)事件
     * @param {Object} e 
     */
    noticeGroupDecrease(e) {

    }

    /**
     * 群管理员变更事件
     * @param {Object} e 
     */
    noticeGroupAdmin(e) {

    }



}



const wsc = new WSClient();
const wsRobotClass = new wsRobot();
const yoyo = {};
// 对象代理
yoyo.client = new Proxy({}, {
    get: (target, key) => (...ages) => {
        return new Promise((resolve, reject) => {
            let eventid = randStr();
            cache.funcArr[eventid] = resolve;//保存函数
            wsc.send(JSON.stringify({
                type: key,//api函数名
                data: ages,//对呀函数的数据
                eventid//事件id
            }));
        });
    }
});//代理client
yoyo.segment = {
    text: (text) => ({ type: 'text', text }),
    face: (id) => ({ type: 'face', id }),
    image: (url) => ({ type: 'image', file: url }),
    record: (url) => ({ type: 'record', url }),
    reply:(id)=>({type:'reply',id}),
    at: (qq) => ({ type: 'at', qq }),
    atall: () => ({ type: 'at', qq: 'all', text: '@全体成员' }),
    xml: (data) => ({ type: 'xml', data }),
};

const cache = {
    count: 1,
    funcArr: {}
};

connect();//连接


wsc.listen("onTextReceived", (msg) => {
    let objData = toJson(msg);
    if (objData && objData.post_type) {
        let eventName = ParseEvent(objData);
        if (!eventName) return;//错误事件名解析

        // 开发的时候可以通过这个得到事件名 (发布的时候请注释)
        log('事件名:', eventName);


        if (typeof wsRobotClass[eventName] == 'function') {
            // 有监听
            wsRobotClass[eventName](objData);//调用这个方法
        } else {
            // 没有监听
            log('没监听的', objData);
        }
    } else if (objData && objData.eventid) {
        if(typeof cache.funcArr[objData.eventid] == 'function') {
            cache.funcArr[objData.eventid](objData.data);//调用回调
            delete cache.funcArr[objData.eventid];//调用完 摧毁掉 释放内存
        }
    }
});

wsc.listen("onError", (msg) => {
    logger.error('发生错误!', msg);

});

wsc.listen("onLostConnection", (code) => {
    logger.error('连接断开 5 秒后尝试重新恢复连接,可能网络波动!');
    setTimeout(() => {
        connect();//连接
    }, 5000);

});

/**
 * json转Object
 * @param {String} text 
 * @returns 
 */
function toJson(text) {
    try {
        return JSON.parse(text);
    } catch (error) {
        return null;
    }
}

/**
 * 连接websocket
 */
function connect() {
    wsc.connectAsync(`ws://${webConfig.host}${webConfig.port ? (':' + webConfig.port) : webConfig.port}/${webConfig.key}`, res => {
        if (!res) {
            logger.error('连接失败 10 秒后尝试重新建立连接,请确保地址和key正确!');
            setTimeout(() => {
                connect();//连接
            }, 10000);
            return;
        }
        colorLog('green', '连接成功,插件正常运行中!');
    });
}

/**
 * 首字母大写
 * @param {String} str 
 * @returns 
 */
function titleCase5(str) {
    return str.toLowerCase().replace(/( |^)[a-z]/g, (L) => L.toUpperCase());
}

/**
 * 解析事件名
 * @param {Object} datas 
 * @returns 
 */
function ParseEvent(datas) {
    let eventName = null;
    try {
        if (!datas.sub_type || datas.sub_type == 'normal') {
            eventName = datas.post_type + titleCase5(datas[`${datas.post_type}_type`]);
        } else {
            eventName = datas.post_type + titleCase5(datas[`${datas.post_type}_type`]) + titleCase5(datas.sub_type);
        }
        return eventName;

    } catch (error) {
        logger.error('解析事件名错误!');
        return null;
    }
}

function randStr() {
    cache.count++;
    let arr_str = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'];
    return String(`${Date.now()}${randNum(100, 999)}`).match(/./g).map(v => (Number(v) % 2 == 0) ? arr_str[Number(v)].toUpperCase() : arr_str[Number(v)]).join('') + cache.count;
}

function randNum(min = 0, max = 255) {
    return Math.floor(Math.random() * max) + min;
}